Scroll to navigation

FCNTL(2) Руководство программиста Linux FCNTL(2)

НАЗВАНИЕ

fcntl - манипуляция файловым дескриптором

КРАТКАЯ СВОДКА

#include <unistd.h>
#include <fcntl.h>

int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd, struct flock *lock);

ОПИСАНИЕ

fcntl выполняет одну из разнообразных операций с файловым дескриптором fd. Какую именно -- определяется параметром cmd:

Ищет первый доступный файловый дескриптор, больший или равный arg, и делает его копией fd.

Это поведение отличается от dup2(2), которая использует именно заданный файловый дескриптор.

Старый и новый дескриптор могут использоваться друг вместо друга. У них общие блокировки, положение указателя в файле и флаги; например, если положение указателя изменяется с помощью lseek на одном из дескрипторов, то оно также меняется на другом.

Два дескриптора, однако, не делят флаг закрыть-при-exec. У копии этот флаг будет установлен в ноль, означая, что он не будет закрыт при выполнении exec.

При успешном завершении возвращается новый дескриптор.

Получить состояние флага закрыть-при-exec. Если бит FD_CLOEXEC результата равен нулю, то файл будет оставаться открытым после выполнения exec, в противном случае он закроется.
Установить флаг закрыть-при-exec, как указано в бите FD_CLOEXEC параметра arg.
Прочитать флаги дескриптора (возвращаются все флаги, установленные при помощи open(2)).
Установить флаги дескриптора в значение, заданное при помощи arg. Можно установить только флаги O_APPEND, O_NONBLOCK и O_ASYNC, прочие флаги не будут затронуты.

Флаги являются общими для копий файлового дескриптора, сделанных с помощью dup(2), fork(2), и т. д.

Флаги и их семантика описаны в open(2).

F_GETLK, F_SETLK и F_SETLKW используются для управления "мягкими" файловыми блокировками. Третий аргумент, lock, является указателем на struct flock (которая может быть перезаписана этим системным вызовом).

Возвращает структуру flock, которая мешает нам получить свою собственную блокировку, или установить поле l_type в значение F_UNLCK, если других блокировок нет.
Блокировка устанавливается (если поле l_type равно F_RDLCK или F_WRLCK) или очищается (если это поле равно F_UNLCK). Если блокировка установлена кем-то ещё, этот вызов возвращает -1 и устанавливает errno в EACCESS или EAGAIN.
Аналогично F_SETLK, только вместо возвращения кода ошибки ожидает, пока блокировка не будет снята. Если в процессе ожидания приходит сигнал, то системный вызов прерывается и, после того, как отработал обработчик сигнала, немедленно возвращает -1 и устанавливает errno в EINTR.

F_GETOWN, F_SETOWN, F_GETSIG и F_SETSIG используются для управления сигналами доступности ввода/вывода:

Получить идентификатор процесса или группы процессов, получающих сигналы SIGIO и SIGURG для событий на файловом дескрипторе fd. Группы процессов возвращаются как отрицательные значения.
Установить идентификатор процесса или группы процессов, которые будут получать сигналы SIGIO и SIGURG для событий на файловом дескрипторе fd. Группы процессов задаются как отрицательные значения. (F_SETSIG может использоваться для задания другого сигнала вместо SIGIO).

Если вы установите флаг O_ASYNC на файловом дескрипторе (передав этот флаг при вызове open(2) или используя команду F_SETFL при вызове fcntl), то сигнал SIGIO будет посылаться каждый раз, когда на этом файловом дескрипторе становится возможен ввод и вывод.

Процесс или группа процессов, которые будут получать сигнал, могут быть выбраны с помощью команды F_SETOWN функции fcntl. Если файловый дескриптор -- это сокет, то при этом будет также выбран адресат сигналов SIGURG, которые посылаются, когда по сокету приходят данные вне основного канала. (SIGURG отсылается в любой ситуации, когда select(2) сообщила бы, что в сокете наличествует "исключительная ситуация".) Если файловый дескриптор соответствует терминальному устройству, то сигналы SIGIO посылаются группе процессов на терминале, выполняющихся не в фоне.

Узнать, какой сигнал посылается, когда становится возможным ввод или вывод. Ноль означает, что посылается SIGIO. Любое другое значение (включая SIGIO) -- это сигнал, который посылается вместо SIGIO, в этом случае доступна дополнительная информация, если обработчик сигнала был установлен с использованием SA_SIGINFO.
Задает сигнал, который посылается, когда становится возможным ввод или вывод. Значение ноль означает, что нужно посылать стандартный сигнал SIGIO. Любое другое значение (включая SIGIO), означает, что нужно послать другой сигнал, и в этом случае также доступна дополнительная информация, если обработчик сигнала был установлен с SA_SIGINFO.

Используя F_SETSIG вместе с ненулевым значением и задавая обработчику сигнала флаг SA_SIGINFO (см. sigaction(2)), можно передать этому обработчику дополнительную информацию о событиях ввода-вывода с помощью структуры siginfo_t. Если поле si_code задает, что источником является SI_SIGIO, то поле si_fd содержит файловый дескриптор, на котором произошло событие. В противном случае нет прямого указания, какие именно файловые дескрипторы участвуют в происходящем, поэтому нужно использовать обычные механизмы (select(2), poll(2), read(2) с флагом O_NONBLOCK, и так далее), чтобы определить, для каких дескрипторов доступен ввод-вывод.

Выбрав сигнал реального времени, соответствующий стандарту POSIX (значение >= SIGRTMIN), можно использовать очереди из множества событий ввода-вывода, использующих один и тот же номер сигнала. (Построение очереди зависит от доступной памяти). Дополнительная информация доступна, если для обработчика установлен SA_SIGINFO, как описано выше.

Используя эти механизмы, можно реализовать полностью асинхронный ввод-вывод без использования, по большей части, select(2) или poll(2).

Использование O_ASYNC, F_GETOWN, F_SETOWN специфично для систем BSD и Linux. F_GETSIG и F_SETSIG специфичны для Linux. POSIX включает в себя асинхронный ввод-вывод и структуру aio_sigevent, с помощью которой достигаются подобные вещи; они также доступны под Linux как часть библиотеки GNU C (Glibc).

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

При успешном завершении возвращаемое значение зависит от операции:

Новый дескриптор.
Значение флага.
Значение флагов.
Владелец дескриптора.
Номер сигнала, который посылается, когда появляется возможность читать или писать, или же ноль, означающий традиционное поведение, сигнал SIGIO.
Все другие команды
Нуль.

При ошибке возвращается -1, а errno устанавливается должным образом.

ОШИБКИ

Операция запрещена блокировкой, установленной другим процессом.
Операция запрещена, потому что файл был отображен в память другим процессом.
fd не является открытым файловым дескриптором.
Обнаружено, что заданная команда F_SETLKW вызвала бы мертвую блокировку.
lock указывает за пределы доступного адресного пространства.
Команда F_SETLKW была прервана сигналом. Команды F_GETLK и F_SETLK, были прерваны сигналом, пока блокировка еще не была проверена или установлена. Чаще всего случается при блокировке сетевого файла (например, при работе с NFS), но иногда может случиться и локально.
Команда F_DUPFD: arg отрицателен или больше, чем максимально разрешенное значение. Команда F_SETSIG: arg не является разрешенным номером сигнала.
Команда F_DUPFD: процесс уже открыл максимальное количество файловых дескрипторов.
Открыто слишком много сегментных блокировок, таблица блокировок полна или же произошла ошибка при сетевой блокировке (при работе с NFS).
Попытка очистить флаг O_APPEND на файле, имеющем атрибут "только-добавление".

ЗАМЕЧАНИЯ

Ошибки, которые возвращает dup2, отличаются от тех, что возвращает F_DUPFD.

СООТВЕТСТВИЕ СТАНДАРТАМ

SVr4, SVID, POSIX, X/OPEN, BSD 4.3. В POSIX.1 указаны только операции F_DUPFD, F_GETFD, F_SETFD, F_GETFL, F_SETFL, F_GETLK, F_SETLK и F_SETLKW. F_GETOWN и F_SETOWN являются BSD-измами, которые не поддерживаются в SVr4; F_GETSIG и F_SETSIG специфичны для Linux. Флаги, допустимые для F_GETFL/F_SETFL -- те, что поддерживаются системным вызовом open(2), и они отличаются на разных системах; O_APPEND, O_NONBLOCK, O_RDONLY, и O_RDWR указаны в POSIX.1. SVr4 поддерживает несколько других опций и флагов, не документированных здесь.

SVr4 документирует дополнительные коды ошибок EIO, ENOLINK и EOVERFLOW.

СМОТРИ ТАКЖЕ

dup2(2), flock(2), open(2), socket(2),

ПЕРЕВОД

Copyright (C) Alexey Mahotkin <alexm@hsys.msk.ru> 1999

12 July 1999 Linux